package com.im.controller;


import com.alibaba.fastjson.JSONObject;
import com.im.annotation.Jwt;
import com.im.config.StringUtil;
import com.im.dao.UserDao;
import com.im.pojo.ImMessage;
import com.im.pojo.ImMq;
import com.im.pojo.ImSend;
import com.im.pojo.ImUser;
import com.im.pojoClass.ImSendList;
import com.im.pojoClass.Result;
import com.im.pojoClass.ResultCode;
import com.im.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author 13349
 */
@Api(tags = {"消息"}, value = "MessageController")
@RestController
@RequestMapping("/message")
@CrossOrigin
public class MessageController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private StringUtil stringUtil;

    @Value("${jwt.key}")
    private String JWT_KEY;

    @Jwt
    @ApiOperation(value = "发送消息", notes = "返回是否成功提示")
    @RequestMapping(value = "/sendMessage", method = RequestMethod.POST)
    public Result sendMessage(@RequestParam String send_id,
                              @RequestParam String receive_id,
                              @RequestParam String message_data,
                              @RequestParam String message_type) {

        // UUID
        String uuid = UUID.randomUUID().toString();
        // 时间戳
        String time = String.valueOf(System.currentTimeMillis());
        // 消息内容
        String trim = message_data.trim();

        // 添加消息
        ImMessage imMessage = new ImMessage(uuid, trim, message_type, time);
        userDao.insertMessage(imMessage);

        // 添加消息发送记录
        // 修改最近联系人消息, 未读数+1
        ImSend imSend = userService.sendMessage(send_id, receive_id, uuid);

        // 创建消息,交给Redis使用
        ImSendList imSendList_redis = new ImSendList();
        imSendList_redis.setImMessage(imMessage);
        imSendList_redis.setImSend(imSend);

        // 判断是否在线
        Boolean user_login = redisTemplate.opsForSet().isMember("userLogin", receive_id);
        // 不在线
        if (!user_login) {
            return new Result(ResultCode.SUCCESS, "消息发送成功");
        }

        // 查出用户信息
        ImUser imUser = userDao.selectUser(send_id);

        // 创建消息,交给消息队列使用
//        ImSendMessage imSendMessage = new ImSendMessage(imSendList_redis, imUser);
        ImMq imMq = new ImMq();
        imMq.setCode("202");
        imMq.setData(imSendList_redis);

        // 序列化
        String s = JSONObject.toJSONString(imMq);

        // 通过RabbitMQ发送
        rabbitTemplate.convertAndSend("im_exchange", "", s);

        return new Result(ResultCode.SUCCESS, "消息发送成功");
    }

    /**
     * MYSQL:QPS200
     * REDIS:QPS800
     */
    @Jwt
    @ApiOperation(value = "查看与好友互发的消息", notes = "返回与好友互发的消息。send_id和receive_id顺序不同，结果也一样")
    @RequestMapping(value = "/selectSendList", method = RequestMethod.POST)
    public Result selectSendList(@RequestParam String send_id,
                                 @RequestParam String receive_id,
                                 @RequestParam Integer page,
                                 @RequestParam Integer num) {

        Integer left = num * page - num;
        Integer right = num * page - 1;

        // 根据两个好友ID生成唯一Key，顺序不限
        // 因为两个好友互发的消息保存在一个Redis的Key里面
        String redis_id_key = stringUtil.str_compare(send_id, receive_id);

        // Redis获取0~20条消息
        ZSetOperations<String, String> opsForZSet = redisTemplate.opsForZSet();
        Set<String> range = opsForZSet.range("im_send" + redis_id_key, left, right);

        // 如果Redis有数据
        if (range.size() != 0) {
            List<ImSendList> collect = range.stream().map(x -> JSONObject.parseObject(x, ImSendList.class)).collect(Collectors.toList());
            return new Result(ResultCode.SUCCESS, collect);
        }

        // Redis为空，从MySQL获取
        ArrayList<ImSendList> selectSendList = userDao.selectSendList(send_id, receive_id, left, num);
        return new Result(ResultCode.SUCCESS, selectSendList);
    }

}